package character;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import game.DataStore;
import game.GameUtil;
import player.Player;
import misc.Vector3i;

public class Character extends Geometry {
    public static final float RADIUS = 0.6f;
    public static final float HEIGHT = 1.8f;
    private int id;
    protected Player player;
    protected ActionQueue actionQueue;
    protected Vector3i boardLocation;
    protected CharacterStatus characterStatus;
    protected Inventory inventory;
    

    @Deprecated
    public Character() {}

    public Character(Player player) {
        super("character", new Sphere(4, 8, RADIUS));
        this.player = player;
        init();
    }

    private void init() {
        id = GameUtil.getNextCharacterId();

        Material mat = new Material(DataStore.assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.randomColor());
        setMaterial(mat);

        addControl(new TickingCharacterControl(new CapsuleCollisionShape(RADIUS, HEIGHT), HEIGHT / 10));
        getCharacterControl().setGravity(0);
        
        actionQueue = new ActionQueue(this);
        characterStatus = new CharacterStatus();
        characterStatus.setHitPoints(50);
        inventory = new Inventory();
    }

    public TickingCharacterControl getCharacterControl() {
        return getControl(TickingCharacterControl.class);
    }

    public Vector3i getBoardLocation() {
        return boardLocation;
    }
    public void setBoardLocation(Vector3i boardLocation) {
        this.boardLocation = boardLocation;
	actionQueue.setQueuedLocation(boardLocation.clone());
    }

    public void movementComplete(Vector3i newLocation) {
        Vector3i oldBoardLocation = boardLocation.clone();
        boardLocation = newLocation;
        DataStore.board.characterMoved(this, oldBoardLocation);
        actionQueue.dequeueFromMovementPath(DataStore.board.getTile(newLocation));
    }

    public List<Vector3i> getValidMoveLocations() {
        List<Vector3i> validLocations = new ArrayList<Vector3i>();
	validLocations.add(actionQueue.getQueuedLocation().clone().addX(1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addX(-1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addZ(1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addZ(-1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addX(1).addZ(1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addX(1).addZ(-1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addX(-1).addZ(1));
	validLocations.add(actionQueue.getQueuedLocation().clone().addX(-1).addZ(-1));
        Iterator<Vector3i> iter = validLocations.iterator();
        while (iter.hasNext()) {
            if (DataStore.board.getTile(iter.next()) == null) {
                iter.remove();
            }
        }
        return validLocations;
    }
    
    public ActionQueue getActionQueue() {
        return actionQueue;
    }

    public CharacterStatus getCharacterStatus() {
        return characterStatus;
    }

    public Inventory getInventory() {
        return inventory;
    }

    public Player getPlayer() {
        return player;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Character other = (Character) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 97 * hash + this.id;
        return hash;
    }

    @Override
    public String toString() {
        return "Character[Id:"+id+", Location:"+boardLocation+"]";
    }
}
